package cn.inswf.framework.mvcs {
	import cn.inswf.framework.core.IContext;
	import cn.inswf.framework.core.IRegister;
	import cn.inswf.injector.Instance;
	import cn.inswf.injector.Singleton;
	import cn.inswf.injector.SingletonEvent;

	import flash.display.DisplayObjectContainer;
	import flash.utils.Dictionary;

	/**
	 * @author hi
	 * 
	 */
	public class Context extends Actor implements IContext {
		private static const singleton : Singleton = new Singleton("framework");
		singleton.setInstance(Singleton, singleton);
		singleton.getInstance(Actor);
		private var map_dict : Dictionary;
		private var notset_dict : Dictionary;

		public function Context(container : DisplayObjectContainer) {
			map_dict = new Dictionary();
			notset_dict = new Dictionary();
			singleton.addEventListener(SingletonEvent.INSTANCE_CREATE, createlistener);
			singleton.addEventListener(SingletonEvent.INSTANCE_NOTSET, notsethandler);
			singleton.setInstance(DisplayObjectContainer, container);
			singleton.setInstance(Context, this);
		}

		private function notsethandler(event : SingletonEvent) : void {
			var instance : Instance = event.instance;
			var qcn : String = getQCN(instance.key, instance.name);
			var list : Array = notset_dict[qcn];
			if (list == null) {
				list = notset_dict[qcn] = [];
			}
			var notset : NotSet = new NotSet();
			notset.instance = event.singleton;
			notset.variable = event.variable;
			list.push(notset);
		}
		/**
		 * 设置是否开启反射功能
		 */
		public function set definitionEnable(value : Boolean) : void {
			singleton.definitionEnable = value;
		}

		private function createlistener(event : SingletonEvent) : void {
			var instance : Instance = event.instance;
			var key : Class = instance.key;
			var name : String = instance.name;
			var has : Boolean;
			var obj : Object;
			var actor : IRegister;
			obj = getInstance(key, name);
			var qn : String = getQCN(key, name);
			if (obj) {
				fillInstance(qn, obj);
				if (obj is IRegister) {
					actor = obj as IRegister;
					actor.onRegister();
				}
			}
			var len : int;
			var list : Array = map_dict[qn];
			if (list == null) {
				return;
			}
			len = list.length;
			while (len--) {
				var _instance : Instance = list[len];
				has = hasInstance(_instance.key, _instance.name);
				if (!has) {
					getInstance(_instance.key, _instance.name);
				}
			}
			delete map_dict[qn];
		}

		private function fillInstance(qcn : String, object : Object) : void {
			var len : int;
			var notsetlist : Array = notset_dict[qcn];
			if (notsetlist == null) return;
			len = notsetlist.length;
			while (len--) {
				var notset : NotSet = notsetlist[len];
				if (notset == null) return;
				var key : Object = notset.instance;
				if (key == null) return;
				var varname : String = notset.variable;
				if (varname == null) return;
				key[varname] = object;
				if (key is IRegister) {
					var actor : IRegister = key as IRegister;
					actor.onInject(varname, object);
				}
			}
		}
		/**
		 * 把两个对象绑定。绑定的对象在目标实例化后实例化
		 * @param actor 要绑定的数据
		 * @param target 绑定目标数据
		 */
		public function bind(actor : Instance, target : Instance) : Boolean {
			if (actor == null || target == null) {
				return false;
			}
			var qcn : String = getQCN(target.key, target.name);
			if (qcn == null) {
				return false;
			}
			var list : Array = map_dict[qcn];
			if (list == null) {
				list = map_dict[qcn] = [];
			}
			list.push(actor);
			return true;
		}
	}
}
